package com.kinghunt.misp.service.impl.userx;

import com.kinghunt.misp.common.constant.SystemConstant;
import com.kinghunt.misp.common.enums.userx.RoleEnum;
import com.kinghunt.misp.common.param.userx.OrganizationParam;
import com.kinghunt.misp.dal.dao.userx.*;
import com.kinghunt.misp.dal.model.userx.*;
import com.kinghunt.misp.service.api.userx.OrganizationWriteService;
import com.bygoodtech.kings.base.utils.ConvertUtil;
import com.bygoodtech.kings.common.dto.ApiResult;
import org.apache.commons.codec.digest.DigestUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.UUID;

import static com.kinghunt.misp.common.utils.PasswordUtils.passwordEncoder;

/**
 * @Description 机构
 * @Author jiangtao
 * @Date 2023/7/5 22:01
 */
@Service
public class OrganizationWriteServiceImpl implements OrganizationWriteService {

    @Autowired(required = false)
    OrganizationDAO organizationDAO;
    @Autowired(required = false)
    OrganizationRoleDAO organizationRoleDAO;
    @Autowired(required = false)
    OrganizationUserDAO organizationUserDAO;
    @Autowired
    private UserDAO userDao;
    @Autowired
    private UserRoleDAO userRoleDAO;

    @Override
    public ApiResult<Long> addOrganization(OrganizationParam organizationParam) {
        List<OrganizationDO> exist = organizationDAO.selectByName(organizationParam.getName(), SystemConstant.SYSTEM_CODE);
        if (!CollectionUtils.isEmpty(exist)) {
            return ApiResult.failOfMessage("创建失败，机构名称已存在");
        }

        OrganizationDO record = ConvertUtil.convert(organizationParam, OrganizationDO.class);
        if (Objects.isNull(record.getAppCode())) {
            record.setAppCode(SystemConstant.SYSTEM_CODE);
        }
        record.setIsDel(Boolean.FALSE);
        organizationDAO.insert(record);
        Long orgId = record.getId();
        if (!CollectionUtils.isEmpty(organizationParam.getRoleIds())) {
            updateOrganizationRole(orgId, organizationParam.getRoleIds());
        }

        // 默认创建一个机构管理员
        autoCreateOrgAdmin(orgId, organizationParam.getName());
        // 默认创建一个IP免登录用户
        autoCreateOrgIpLoginUser(orgId, organizationParam.getName());

        return ApiResult.ok(orgId);
    }

    /**
     * 创建机构时自动创建一个该机构的管理员
     *
     * @param orgId
     * @param orgName
     */
    private void autoCreateOrgAdmin(Long orgId, String orgName) {
        /*UserDO newUserDO = new UserDO();
        newUserDO.setAppCode(SystemConstant.SYSTEM_CODE);
        newUserDO.setOrganizationId(orgId);
        newUserDO.setOrganizationName(orgName);
        newUserDO.setUsername(SystemConstant.DEFAULT_ORG_ADMIN);
        newUserDO.setRealname("管理员");
        newUserDO.setNickname("管理员");
        newUserDO.setGender(1);
        newUserDO.setStatus(0);
        newUserDO.setRoleId(3L);
        newUserDO.setIsDel(Boolean.FALSE);
        newUserDO.setSalt(DigestUtils.md5Hex(UUID.randomUUID().toString() + System.currentTimeMillis() + UUID.randomUUID().toString()));
        newUserDO.setPassword(passwordEncoder(SystemConstant.DEFAULT_USER_PASSWORD, newUserDO.getSalt()));
        newUserDO.setStatus(0);
        userDao.addUser(newUserDO);
        Long userId = newUserDO.getId();

        UserRoleDO userRoleDO = new UserRoleDO();
        userRoleDO.setUserId(userId);
        userRoleDO.setRoleId(newUserDO.getRoleId());
        userRoleDAO.insertSelective(userRoleDO);

        OrganizationUserDO organizationUserDO = new OrganizationUserDO();
        organizationUserDO.setUserId(userId);
        organizationUserDO.setOrganizationId(orgId);
        organizationUserDAO.insertSelective(organizationUserDO);*/
        autoCreateUser(orgId, orgName, SystemConstant.DEFAULT_ORG_ADMIN, RoleEnum.ORG_ADMIN);
    }

    /**
     * 创建机构时自动创建一个该机构的管理员
     *
     * @param orgId
     * @param orgName
     */
    private void autoCreateOrgIpLoginUser(Long orgId, String orgName) {
        autoCreateUser(orgId, orgName, SystemConstant.DEFAULT_ORG_IP_LOGIN, RoleEnum.ORG_IP);
    }

    private void autoCreateUser(Long orgId, String orgName, String username, RoleEnum role) {
        UserDO newUserDO = new UserDO();
        newUserDO.setAppCode(SystemConstant.SYSTEM_CODE);
        newUserDO.setOrganizationId(orgId);
        newUserDO.setOrganizationName(orgName);
        newUserDO.setUsername(username);
        newUserDO.setRealname(role.getName());
        newUserDO.setNickname(role.getName());
        newUserDO.setGender(1);
        newUserDO.setStatus(0);
        newUserDO.setRoleId(role.getId());
        newUserDO.setIsDel(Boolean.FALSE);
        newUserDO.setSalt(DigestUtils.md5Hex(UUID.randomUUID().toString() + System.currentTimeMillis() + UUID.randomUUID().toString()));
        newUserDO.setPassword(passwordEncoder(SystemConstant.DEFAULT_USER_PASSWORD, newUserDO.getSalt()));
        newUserDO.setStatus(0);
        userDao.addUser(newUserDO);
        Long userId = newUserDO.getId();

        UserRoleDO userRoleDO = new UserRoleDO();
        userRoleDO.setUserId(userId);
        userRoleDO.setRoleId(newUserDO.getRoleId());
        userRoleDAO.insertSelective(userRoleDO);

        OrganizationUserDO organizationUserDO = new OrganizationUserDO();
        organizationUserDO.setUserId(userId);
        organizationUserDO.setOrganizationId(orgId);
        organizationUserDAO.insertSelective(organizationUserDO);
    }

    @Override
    public ApiResult<Boolean> updateOrganizationInfo(OrganizationParam organizationParam) {
        OrganizationDO record = ConvertUtil.convert(organizationParam, OrganizationDO.class);
        organizationDAO.updateByPrimaryKeySelective(record);
        updateOrganizationRole(organizationParam.getId(), organizationParam.getRoleIds());
        return ApiResult.ok(true);
    }

    @Override
    public ApiResult<Boolean> deleteOrganization(Long organizationId) {
        List<Long> userIds = organizationUserDAO.selectUserIdsByOrgId(organizationId);
        if (! CollectionUtils.isEmpty(userIds)) {
            return ApiResult.failOfMessage("该机构存在关联人员，不可删除");
        }
        OrganizationDO record = new OrganizationDO();
        record.setId(organizationId);
        record.setIsDel(true);
        organizationDAO.updateByPrimaryKeySelective(record);
        organizationRoleDAO.deleteByOrgId(organizationId);
        return ApiResult.ok(true);
    }

    /**
     * 更新机构角色关系表
     *
     * @param organizationId 机构ID
     * @param roleIds 角色ID
     */
    private void updateOrganizationRole(Long organizationId, List<Long> roleIds) {
        organizationRoleDAO.deleteByOrgId(organizationId);
        if (! CollectionUtils.isEmpty(roleIds)) {
            List<OrganizationRoleDO> organizationRoleDOS = new ArrayList<>();
            for (Long roleId : roleIds) {
                OrganizationRoleDO orDO = new OrganizationRoleDO();
                orDO.setOrganizationId(organizationId);
                orDO.setRoleId(roleId);
                organizationRoleDOS.add(orDO);
            }
            organizationRoleDAO.insertBatch(organizationRoleDOS);
        }

        //TODO: 考虑是否需要更新用户角色
    }
}
